package com.orderplus.opshop.common.util;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Set;

/**
 * HTTP转发接口工具类
 * Created by zhouxj6112 on 2018/12/19.
 */
public class HttpRequestUtil {

	private static CloseableHttpClient httpClient;

	static {
		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
		cm.setMaxTotal(100);
		cm.setDefaultMaxPerRoute(20);
		cm.setDefaultMaxPerRoute(50);
		httpClient = HttpClients.custom().setConnectionManager(cm).build();
	}

	/**
	 * get方法
	 *
	 * @param url
	 * @param parameters
	 * @return
	 */
	public static String get(String url, Map<String, String> parameters) {
		CloseableHttpResponse response = null;
		BufferedReader in = null;
		String result = "";
		try {
			String urlString = url;
			if (!url.contains("?")) {
				urlString += "?";
			}
			if (parameters != null && parameters.size() > 0) {
				for (Map.Entry<String, String> entry : parameters.entrySet()) {
					urlString += (entry.getKey() + "=" + entry.getValue() + "&");
				}
			}
			HttpGet httpGet = new HttpGet(urlString);
			RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();
			httpGet.setConfig(requestConfig);
			httpGet.setConfig(requestConfig);
			httpGet.addHeader("Content-type", "application/json; charset=utf-8");
			httpGet.setHeader("Accept", "application/json");
			response = httpClient.execute(httpGet);
			in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			result = sb.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != response) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * post方法
	 *
	 * @param url
	 * @param parameters
	 * @return
	 */
	public static String post(String url, Map<String, Object> parameters) {
		CloseableHttpResponse response = null;
		BufferedReader in = null;
		String result = "";
		try {
			HttpPost httpPost = new HttpPost(url);
			RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();
			httpPost.setConfig(requestConfig);
			httpPost.setConfig(requestConfig);
			httpPost.addHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
			httpPost.setHeader("Accept", "*");
//            String jsonString = JSONUitl.obj2String(parameters);
//            httpPost.setEntity(new StringEntity(jsonString, Charset.forName("UTF-8")));
			httpPost.setEntity(new StringEntity(getNamValStr(parameters), Charset.forName("UTF-8")));
			response = httpClient.execute(httpPost);
			in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			result = sb.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != response) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * 转发文件流
	 *
	 * @param url
	 * @param multipartFile
	 * @return
	 */
	public static String transmitFile(String url, MultipartFile multipartFile) {
		String rString = "";
		InputStream inputStream = null;
		try {
			inputStream = multipartFile.getInputStream();
			MultipartEntityBuilder builder = MultipartEntityBuilder.create();
			builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
			//第一个参数为 相当于 Form表单提交的file框的name值
			//第二个参数就是我们要发送的InputStream对象了
			//第三个参数是文件名
			builder.addBinaryBody("image", inputStream, ContentType.create("multipart/form-data"), "image.jpg");
			//4)构建请求参数 普通表单项
			StringBody stringBody = new StringBody("12", ContentType.MULTIPART_FORM_DATA);
			builder.addPart("id", stringBody);
			// 跟后端的校验参数
			builder.addTextBody("key", "OPShop-001" + "-middle");
			HttpEntity entity = builder.build();
			HttpPost post = new HttpPost(url);
			post.setEntity(entity);
			//发送请求
			CloseableHttpClient client = HttpClients.createDefault();
			HttpResponse httpResponse = client.execute(post);
			entity = httpResponse.getEntity();
			if (entity != null) {
				inputStream = entity.getContent();
				//转换为字节输入流
				rString = HttpUtil.convertStreamToString(inputStream);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return rString;
	}

	public static String getNamValStr(Map<String, Object> map) {
		StringBuilder str = new StringBuilder();
		Set<String> set = map.keySet();
		for (String key : set) {
			str.append(key).append("=").append(map.get(key).toString()).append("&");
		}
		return str.toString().substring(0, str.lastIndexOf("&"));
	}

	/**
	 * 转发文件流
	 *
	 * @param url
	 * @param multipartFile
	 * @return
	 */
	public static String transmitFile(String url, MultipartFile multipartFile, Map<String, String> addtionals) {
		String rString = "";
		InputStream inputStream = null;
		try {
			inputStream = multipartFile.getInputStream();
			MultipartEntityBuilder builder = MultipartEntityBuilder.create();
			builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
			//第一个参数为 相当于 Form表单提交的file框的name值
			//第二个参数就是我们要发送的InputStream对象了
			//第三个参数是文件名
			builder.addBinaryBody("image", inputStream, ContentType.create("multipart/form-data"), "image.jpg");
			//4)构建请求参数 普通表单项
			StringBody stringBody = new StringBody("12", ContentType.MULTIPART_FORM_DATA);
			builder.addPart("id", stringBody);
			// 跟后端的校验参数
			builder.addTextBody("key", "OPShop-001" + "-middle");
			if (addtionals != null) {
				for (Map.Entry<String, String> entry : addtionals.entrySet()) {
					if (entry.getValue() == null) {
						continue;
					}
					builder.addTextBody(entry.getKey(), entry.getValue());
				}
			}
			HttpEntity entity = builder.build();
			HttpPost post = new HttpPost(url);

			post.setEntity(entity);
			//发送请求
			CloseableHttpClient client = HttpClients.createDefault();
			HttpResponse httpResponse = client.execute(post);
			entity = httpResponse.getEntity();
			if (entity != null) {
				inputStream = entity.getContent();
				//转换为字节输入流
				rString = HttpUtil.convertStreamToString(inputStream);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return rString;
	}

	public static String postFileData(String url, MultipartFile[] files, Map<String, String> parameters) {
		String rString = null;
		InputStream inputStream = null;
		try {
			rString = "";
			MultipartEntityBuilder builder = MultipartEntityBuilder.create();
			builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
			for (MultipartFile file : files) {
				builder.addBinaryBody("files", file.getInputStream(), ContentType.create("multipart/form-data"), file.getOriginalFilename());
			}
			if (parameters != null) {
				for (Map.Entry<String, String> entry : parameters.entrySet()) {
					if (entry.getValue() == null) {
						continue;
					}
					builder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create("multipart/form-data", "UTF-8"));
				}
			}
			HttpEntity entity = builder.build();
			HttpPost post = new HttpPost(url);
			post.setEntity(entity);
			//发送请求
			CloseableHttpClient client = HttpClients.createDefault();
			HttpResponse httpResponse = client.execute(post);
			entity = httpResponse.getEntity();
			if (entity != null) {
				inputStream = entity.getContent();
				//转换为字节输入流
				rString = HttpUtil.convertStreamToString(inputStream);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return rString;
	}

	public static String downloadFile(String fileUrl) {
		// 先判断本地是否已经下载过了
		FileUtil.checkFile();
		String distPath = FileUtil.getImagePath();
		String md5 = DigestUtils.md5Hex(fileUrl);
		String filePath = distPath + "\\" + md5 + ".jpg";
		File distFile = new File(filePath);
		if (distFile.exists()) {
			return distFile.getPath();
		}

		HttpURLConnection conn = null;
		InputStream inputStream = null;
		BufferedInputStream bis = null;
		FileOutputStream out = null;
		try {
			File fileNew = new File(filePath);
			out = new FileOutputStream(fileNew);
			// 建立链接
			URL httpUrl = new URL(fileUrl);
			conn = (HttpURLConnection) httpUrl.openConnection();
			//以Post方式提交表单，默认get方式
			conn.setRequestMethod("GET");
			conn.setDoInput(true);
			conn.setDoOutput(true);
			// post方式不能使用缓存
			conn.setUseCaches(false);
			//连接指定的资源
			conn.connect();
			//获取网络输入流
			inputStream = conn.getInputStream();
			bis = new BufferedInputStream(inputStream);
			byte b[] = new byte[1024];
			int len = 0;
			while ((len = bis.read(b)) != -1) {
				out.write(b, 0, len);
			}
			System.out.println("下载完成...");
		} catch (Exception e) {
			e.printStackTrace();
			filePath = null;
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (bis != null) {
					bis.close();
				}
				if (inputStream != null) {
					inputStream.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		return filePath;
	}

}
